package com.dongnam.quanly.web.danhmuc.phongban;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import java.io.UnsupportedEncodingException;

import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.TreeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dongnam.quanly.common.controller.PhongBanController;
import com.dongnam.quanly.common.exceptions.DatabaseException;
import com.dongnam.quanly.common.model.KhoHang;
import com.dongnam.quanly.common.model.NhomDoiTac;
import com.dongnam.quanly.common.model.PhongBan;
import com.dongnam.quanly.web.UserBean;
import com.dongnam.quanly.web.danhmuc.khohang.KhoHangModel;
import com.dongnam.quanly.web.util.CsvUtil;
import com.dongnam.quanly.web.util.WebUtil;

@ManagedBean(name = "PhongBanBean")
@SessionScoped
public class PhongBanBean implements Serializable {

	private static final Logger logger = LoggerFactory.getLogger(PhongBanBean.class);
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@ManagedProperty(value = "#{UserBean}")
	private UserBean userBean;
	private TreeNode phongBanRoot;
	private TreeNode selectedNode;
	private boolean flag = false;

	// for add PhongBan
	private String maPhongBan;
	private String tenPhongBan;
	private String thuocPhongBan;
	private String diengiai;
	private boolean edit = false;
	// for download file
	private StreamedContent file;

	// for load danh sach phong ban
	private PhongBanController phongbanController;
	private List<PhongBan> listphongban;

	// for edit phongBan
	private PhongBan selectedPhongBan;

	public PhongBanController getPhongbanController() {

		if (phongbanController == null)
			phongbanController = new PhongBanController();
		return phongbanController;
	}

	public void downloadFileCSV() {
		File excelfile = new File("PHONG_BAN.xls");
		List<PhongBan> list = getPhongbanController().findAll();
		int length = list.size();
		try {
			WritableWorkbook workbook = Workbook.createWorkbook(excelfile);
			WritableSheet sheet = workbook.createSheet("First Sheet", 0);

			// style for title
			WritableFont titlefont = new WritableFont(WritableFont.ARIAL, 16, WritableFont.BOLD);
			WritableCellFormat titleformat = new WritableCellFormat(titlefont);
			titleformat.setAlignment(Alignment.LEFT);
			titleformat.setWrap(false);

			// style for content
			WritableFont contentfont = new WritableFont(WritableFont.ARIAL, 13);
			WritableCellFormat contentformat = new WritableCellFormat(contentfont);
			contentformat.setAlignment(Alignment.LEFT);
			contentformat.setWrap(false);

			// thiet lap tieu de
			sheet.setColumnView(0, 30);
			sheet.setColumnView(1, 30);
			sheet.setColumnView(2, 30);
			sheet.setColumnView(3, 30);

			sheet.addCell(new Label(0, 0, "Mã Phòng Ban", titleformat));
			sheet.addCell(new Label(1, 0, "Tên Phòng Ban", titleformat));
			sheet.addCell(new Label(2, 0, "Thuộc Phòng Ban", titleformat));
			sheet.addCell(new Label(3, 0, "Diễn Giải", titleformat));

			for (int i = 0; i < length; i++) {

				sheet.addCell(new Label(0, i + 1, list.get(i).getMaPhongBan(), contentformat));
				sheet.addCell(new Label(1, i + 1, list.get(i).getTenPhongBan(), contentformat));
				sheet.addCell(new Label(2, i + 1, list.get(i).getThuocPhongBan(), contentformat));
				sheet.addCell(new Label(3, i + 1, list.get(i).getDienGiai(), contentformat));

			}

			workbook.write();
			workbook.close();

			file = new DefaultStreamedContent(new FileInputStream(excelfile), "application/csv", "PHONG_BAN.xls",
					"UTF-8");

		} catch (IOException | WriteException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	public void handleFileUpload(FileUploadEvent event) {

		logger.debug("process upload file ");
		Workbook w;
		boolean rollback = false;
		List<PhongBan> list = new ArrayList<PhongBan>();
		try {
			w = Workbook.getWorkbook(event.getFile().getInputstream());
			// Get the first sheet
			Sheet sheet = w.getSheet(0);
			// Loop over first 10 column and lines

			for (int row = 1; row < sheet.getRows(); row++) {

				logger.debug("row " + row);
				Cell cell_ma = sheet.getCell(0, row);
				Cell cell_ten = sheet.getCell(1, row);
				Cell cell_thuoc = sheet.getCell(2, row);
				Cell cell_dienGiai = sheet.getCell(3, row);

				PhongBan pb = new PhongBan();
				pb.setMaPhongBan(cell_ma.getContents());
				pb.setTenPhongBan(cell_ten.getContents());
				pb.setThuocPhongBan(cell_thuoc.getContents());
				pb.setDienGiai(cell_dienGiai.getContents());
				boolean isHasChild = false;
				for (int i = 0; i < sheet.getRows(); i++) {
					Cell cell_thuoc_ndt_test = sheet.getCell(2, i);
					if (cell_ma.getContents().equals(cell_thuoc_ndt_test.getContents())) {
						isHasChild = true;
						break;
					}
				}
				pb.setIsHasChild(isHasChild);
				list.add(pb);
			}
		} catch (BiffException | IOException e) {
			e.printStackTrace();
			rollback = true;
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful : Database error : "
					+ e.getMessage(), "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

		if (!rollback) {
			getPhongbanController().batchSaveOrUpdate(list);
		}

		loadPhongBan();
	}

	public void resetFormAdd() {
		maPhongBan = null;
		tenPhongBan = null;
		thuocPhongBan = null;
		diengiai = null;
	}

	public void notifyAdd() {
		edit = false;
		resetFormAdd();
		listphongban = getPhongbanController().findAll();
	}

	public void findNote(TreeNode root, PhongBan phongBan) {

		if (!flag) {
			if (root.isLeaf()) {

				if (((PhongBan) root.getData()).getMaPhongBan().equals(phongBan.getMaPhongBan())) {
					flag = true;
					this.selectedNode = root;
				}
			}

			else {

				if (root.getData() != null) {
					if (((PhongBan) root.getData()).getMaPhongBan().equals(phongBan.getMaPhongBan())) {
						flag = true;
						this.selectedNode = root;
					} else {
						List<TreeNode> listnode = root.getChildren();
						int length = listnode.size();
						for (int i = 0; i < length; i++) {
							findNote(listnode.get(i), phongBan);
						}
					}
				} else {
					List<TreeNode> listnode = root.getChildren();
					int length = listnode.size();
					for (int i = 0; i < length; i++) {
						findNote(listnode.get(i), phongBan);
					}
				}

			}
		}
	}

	public void notifyEdit(PhongBan phongban) {
		edit = true;
		this.selectedPhongBan = phongban;
		maPhongBan = this.selectedPhongBan.getMaPhongBan();
		tenPhongBan = this.selectedPhongBan.getTenPhongBan();
		thuocPhongBan = this.selectedPhongBan.getThuocPhongBan();
		diengiai = this.selectedPhongBan.getDienGiai();

		List<String> listtest = new ArrayList<String>();

		this.flag = false;
		this.selectedNode = null;
		findNote(this.phongBanRoot, phongban);
		if (this.selectedNode != null)

			deepTree(this.selectedNode, listtest);

		for (int i = 0; i < listtest.size(); i++) {
			logger.info(listtest.get(i) + "hsadb");
		}

		if (listtest.size() != 0)
			listphongban = getPhongbanController().listPhongBanExclude(listtest);
		else
			listphongban = getPhongbanController().findAll();
	}

	public void deepTree(TreeNode root, List<String> list) {
		if (root.isLeaf()) {
			logger.info("Name " + ((PhongBan) root.getData()).getMaPhongBan());
			list.add(((PhongBan) root.getData()).getMaPhongBan());
		} else {
			logger.info("Name " + ((PhongBan) root.getData()).getMaPhongBan());
			list.add(((PhongBan) root.getData()).getMaPhongBan());
			List<TreeNode> listnode = root.getChildren();
			int length = listnode.size();
			for (int i = 0; i < length; i++) {
				deepTree(listnode.get(i), list);
			}
		}
	}

	public void removePhongBan() {

		if (this.selectedPhongBan != null) {
			getPhongbanController().makeTransient(this.selectedPhongBan);

			List<String> listtest = new ArrayList<String>();

			this.flag = false;
			this.selectedNode = null;
			findNote(this.phongBanRoot, this.selectedPhongBan);
			if (this.selectedNode != null)

				deepTree(this.selectedNode, listtest);

			for (int i = 0; i < listtest.size(); i++) {
				logger.info(listtest.get(i) + "hsadb");
			}

			getPhongbanController().batchDelete(getPhongbanController().listPhongBanInclude(listtest));
			loadPhongBan();
			;
			listphongban = getPhongbanController().findAll();
		}

	}

	public List<PhongBan> findListByParent(String parentID) {
		PhongBan exam = new PhongBan();
		exam.setThuocPhongBan(parentID);
		return getPhongbanController().findByExample(exam);

	}

	private void setParent() {
		if (!this.thuocPhongBan.equals("root")) {
			PhongBan pbparent = getPhongbanController().findById(this.thuocPhongBan, false);
			if (pbparent != null) {
				logger.debug("Phong Ban parent: " + pbparent.getMaPhongBan());
				pbparent.setIsHasChild(Boolean.TRUE);
				getPhongbanController().makePersistent(pbparent);
			}
		}
	}

	public void save() {

		RequestContext context = RequestContext.getCurrentInstance();
		try {
			if (edit) {

				if (this.selectedPhongBan != null) {

					logger.debug("Edit new PhongBan");

					this.selectedPhongBan.setUpdateBy(userBean.getUser().getUserId());
					this.selectedPhongBan.setMaPhongBan(this.maPhongBan);
					this.selectedPhongBan.setTenPhongBan(this.tenPhongBan);
					this.selectedPhongBan.setThuocPhongBan(this.thuocPhongBan);
					this.selectedPhongBan.setDienGiai(this.diengiai);

					getPhongbanController().makePersistent(this.selectedPhongBan);
					// change state of parent
					setParent();
					context.addCallbackParam("opSuccess", true);
				}

			} else {

				logger.debug("Add new PhongBan");
				PhongBan pb = new PhongBan();
				pb.setCreateBy(userBean.getUser().getUserId());
				pb.setUpdateBy(userBean.getUser().getUserId());

				pb.setMaPhongBan(this.maPhongBan);
				pb.setTenPhongBan(this.tenPhongBan);
				pb.setThuocPhongBan(this.thuocPhongBan);
				pb.setDienGiai(this.diengiai);
				pb.setIsHasChild(Boolean.FALSE);

				getPhongbanController().makePersistent(pb);

				// change state of parent
				if (!this.thuocPhongBan.equals("root")) {
					setParent();
				}

				listphongban = getPhongbanController().findAll();
				context.addCallbackParam("opSuccess", true);

			}
		} catch (DatabaseException e) {
			e.printStackTrace();
			logger.debug("Database error" + e.getMessage());
			context.addCallbackParam("opSuccess", false);

			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful : Database error : "
					+ e.getMessage(), "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

		loadPhongBan();

	}

	public void loadPhongBan() {
		if (phongBanRoot == null)
			phongBanRoot = new DefaultTreeNode();

		phongBanRoot.getChildren().clear();

		List<PhongBan> listgroup = loadParents();
		List<PhongBan> listchild = loadChilds();
		createListPhongBan("root", phongBanRoot, listgroup, listchild, listgroup.size(), listchild.size());
		this.phongBanRoot.setExpanded(true);
	}

	private List<PhongBan> loadChilds() {
		PhongBan exam = new PhongBan();
		exam.setIsHasChild(Boolean.FALSE);
		return getPhongbanController().findByExample(exam);
	}

	private List<PhongBan> loadParents() {
		PhongBan exam = new PhongBan();
		exam.setIsHasChild(Boolean.TRUE);
		return getPhongbanController().findByExample(exam);

	}

	public void createListPhongBan(String parentID, TreeNode parent, List<PhongBan> listgroups,
			List<PhongBan> listphongban, int lengthgroups, int lenghtphongban) {

		for (int i = 0; i < lengthgroups; i++) {
			if (listgroups.get(i).getThuocPhongBan().equals(parentID)) {
				TreeNode group = new DefaultTreeNode(listgroups.get(i), parent);
				createListPhongBan(listgroups.get(i).getMaPhongBan(), group, listgroups, listphongban, lengthgroups,
						lenghtphongban);
			}
		}

		for (int j = 0; j < lenghtphongban; j++) {

			if (listphongban.get(j).getThuocPhongBan().equals(parentID)) {
				new DefaultTreeNode(listphongban.get(j), parent);
			}
		}
	}

	public StreamedContent getFile() {
		return file;
	}

	public void setFile(StreamedContent file) {
		this.file = file;
	}

	public UserBean getUserBean() {
		return userBean;
	}

	public void setUserBean(UserBean userBean) {
		this.userBean = userBean;
	}

	public TreeNode getPhongBanRoot() {
		return phongBanRoot;
	}

	public void setPhongBanRoot(TreeNode phongBanRoot) {
		this.phongBanRoot = phongBanRoot;
	}

	public String getMaPhongBan() {
		return maPhongBan;
	}

	public void setMaPhongBan(String maPhongBan) {
		this.maPhongBan = maPhongBan;
	}

	public boolean isEdit() {
		return edit;
	}

	public void setEdit(boolean edit) {
		this.edit = edit;
	}

	public String getTenPhongBan() {
		return tenPhongBan;
	}

	public void setTenPhongBan(String tenPhongBan) {
		this.tenPhongBan = tenPhongBan;
	}

	public String getThuocPhongBan() {
		return thuocPhongBan;
	}

	public void setThuocPhongBan(String thuocPhongBan) {
		this.thuocPhongBan = thuocPhongBan;
	}

	public String getDiengiai() {
		return diengiai;
	}

	public void setDiengiai(String diengiai) {
		this.diengiai = diengiai;
	}

	public List<PhongBan> getListphongban() {

		if (listphongban == null) {
			listphongban = getPhongbanController().findAll();
		}

		return listphongban;
	}

	public void setListphongban(List<PhongBan> listphongban) {
		this.listphongban = listphongban;
	}

	public PhongBan getSelectedPhongBan() {
		return selectedPhongBan;
	}

	public void setSelectedPhongBan(PhongBan selectedPhongBan) {
		this.selectedPhongBan = selectedPhongBan;
	}

	public void reloadPage() {
		listphongban = getPhongbanController().findAll();
		loadPhongBan();
		WebUtil.redirect("/pages/danhmuc/phongBan.xhtml");
	}

}
